﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Zarion_Quest.Base
{
    abstract class Object2D
    {

        private Texture2D texture;
        /// <summary>
        /// Texture image for your object.
        /// </summary>
        /// <returns>Returns current texture being used.</returns>
        /// <param name="Set">Sends the texture to be used.</param>
        public Texture2D Texture
        {
            get { return texture; }
            set { texture = value; }
        }


        private Color color;
        /// <summary>
        /// Color tint for your object.
        /// </summary>
        /// <returns>Returns current color tint for object.</returns>
        /// <param name="Set">Sends the current color Tint to be used.</param>
        public Color ObjectColor
        {
            get { return color; }
            set { color = value; }
        }



        private Vector2 position;
        /// <summary>
        /// Position for your object.
        /// </summary>
        /// <returns>Current position of game object.</returns>
        /// <param name="Set">Vector2 to define the position for object.</param>
        public Vector2 Position
        {
            get { return position; }
            set { position = value; }
        }


        private Vector2 middlePoint;
        /// <summary>
        /// Defines the 0,0 of the game object in the middle of the texture.
        /// </summary>
        /// <returns>0,0 position of the object in the middle of the texture.</returns>
        /// <param name="Set">Defines middle position of the object</param>
        public Vector2 MiddlePoint
        {
            get { return middlePoint; }
            set { middlePoint = value; }
        }


        private Vector2 scaleVector;
        /// <summary>
        /// Scale factor in a vector used to define ingame alterations to your object.
        /// </summary>
        /// <returns></returns>
        /// <param name="Set"></param>
        public Vector2 ScaleVector
        {
            get { return scaleVector; }
            set { scaleVector = value; }
        }


        private float rotation;
        /// <summary>
        /// Rotation for the object.
        /// </summary>
        /// <returns></returns>
        /// <param name="Set"></param>
        public float Rotation
        {
            get { return rotation; }
            set { rotation = value; }
        }


        private float alpha;
        /// <summary>
        /// Opacity of the object.
        /// </summary>
        /// <returns></returns>
        /// <param name="Set"></param>
        public float Alpha
        {
            get { return alpha; }
            set { alpha = value; }
        }

        // SpriteEffects para ser usado no objeto, crio ele como padrão None
        private SpriteEffects objectSpriteEffects;
        /// <summary>
        /// SpriteEffects for the object.
        /// </summary>
        /// <returns></returns>
        /// <param name="Set"></param>
        public SpriteEffects ObjectSpriteEffects
        {
            get { return objectSpriteEffects; }
            set { objectSpriteEffects = value; }
        }

        protected float layerDepth;
        /// <summary>
        /// Layer Depth of the object.
        /// </summary>
        /// <returns></returns>
        /// <param name="Set"></param>
        public float LayerDepth
        {
            get { return layerDepth; }
            set { layerDepth = value; }
        }

        private bool visible;
        /// <summary>
        /// Alters wether or not the object will be drawn.
        /// </summary>
        /// <returns></returns>
        /// <param name="Set"></param>
        public bool Visible
        {
            get { return visible; }
            set { visible = value; }
        }


        private Rectangle collisionBounds;
        /// <summary>
        /// Collision controller for game objects.
        /// </summary>
        /// <returns></returns>
        /// <param name="Set"></param>
        public Rectangle CollisionBounds
        {
            get { return collisionBounds; }
            set { collisionBounds = value; }
        }
        // layer

        /// <summary>
        /// Construct for Object2D class.
        /// </summary>
        /// <param name="texture">Texture to be used when drawing your object.</param>
        public Object2D(Texture2D texture)
        {
            this.texture = texture;
            position = new Vector2(200, 200);
            color = Color.White;
            rotation = 0;
            middlePoint = new Vector2(texture.Width / 2, texture.Height / 2);
            scaleVector = new Vector2(1f, 1f);
            visible = true;
            alpha = 1f;
            objectSpriteEffects = SpriteEffects.None;
            layerDepth = 0.5f;

            calculateRectangle();
        }

        public virtual void calculateRectangle()
        {
            collisionBounds = new Rectangle((int)(position.X - (middlePoint.X * scaleVector.X)),
                (int)(position.Y - (middlePoint.Y * scaleVector.Y)),
                (int)(texture.Width * scaleVector.X),
                (int)(texture.Height * scaleVector.Y));
        }

        /// <summary>
        /// Tests collision between two game objects.
        /// </summary>
        /// <param name="object2D">Receives the object to be tested for collision</param>
        /// <returns>If true the two objects are colliding, otherwise will return false.</returns>
        public bool hitTestObject(Object2D object2D)
        {
            this.calculateRectangle();
            object2D.calculateRectangle();

            if (this.collisionBounds.Intersects(object2D.collisionBounds))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Draws your object on the screen
        /// </summary>
        /// <param name="spriteBatch"></param>
        public virtual void Draw(SpriteBatch spriteBatch)
        {
            if (visible == true)
            {
                spriteBatch.Draw(texture, position, null, color * alpha, MathHelper.ToRadians(rotation), middlePoint, scaleVector, objectSpriteEffects, layerDepth);

            }
        }

        /// <summary>
        /// Método que deve ser sobrescrito com o que deve ocorrer caso o objeto seja atingido por um tiro.
        /// Fiquei meio sem opções e por isso coloquei ele aqui, aberto a sugestões.
        /// Não é abstrato pois não considero obrigatório a implentação dele em todos os objetos...
        /// </summary>
        public virtual void collisionNotifier(Object2D caller)
        {
        }
    }
}